package com.xxl.job.executor.protocol;

import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.executor.utils.ByteUtil;
import org.apache.commons.lang3.StringUtils;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;

public class TCPProtocol {


    private String inetHost = null;
    private int inetPort;
    private Socket socket;
    ServerSocket serverSocket;

    public TCPProtocol(){

    }

    public TCPProtocol(String inetHost, int inetPort) {
        this.inetHost = inetHost;
        this.inetPort = inetPort;
    }
    public boolean sever() {
        // 1.创建服务器ServerSocket对象和系统指定的端口号
        try {
            serverSocket = new ServerSocket(55000);
            socket = serverSocket.accept();

            return true;
        } catch (IOException e) {
            XxlJobLogger.log("创建 <" + inetHost + " TCPProtocol> 成功，等待接收数据 ");
            return false;
        }
    }
    public boolean connect() {
        try {
            socket = new Socket();
            SocketAddress socketAddress = new InetSocketAddress(inetHost, inetPort);
            socket.connect(socketAddress, 3000);
            socket.setSoTimeout(3000);
            return true;
        } catch (IOException e) {
            XxlJobLogger.log("TCPProtocol连接 <" + inetHost + ":" + inetPort + "> 失败!!!  " + e.getMessage());
            return false;
        }
    }

    public boolean sendData(byte[] sMessage) {
        try {
            OutputStream os = socket.getOutputStream();
            os.write(sMessage);
            os.flush();
            return true;
        } catch (IOException e) {
            XxlJobLogger.log("TCPProtocol Send Mesaage Error!!!"+e.getMessage());
            return false;
        }
    }

    public byte[] recvData(){
        String recvMessage = "";
        int iMaxLenth = 2048;
        int iRecvMessageLen = 0;
        byte[] bString = new byte[iMaxLenth];
        try {
            InputStream is = socket.getInputStream();
            DataInputStream input = new DataInputStream(is);

           // while (true) {
                try{
                    int i = input.read(bString);
                    iRecvMessageLen += i;
                    recvMessage += ByteUtil.bytes2hexStr(bString);
//                    TimeUnit.SECONDS.sleep(recvSleep);
                }catch (IOException e) {
                    XxlJobLogger.log("Recv Message End");
                //    break;
                }
         //   }
            if(!StringUtils.isNotBlank(recvMessage)){
                XxlJobLogger.log("Recv message is null");
                return null;
            }
            byte[] bTemp = ByteUtil.hexStr2bytes(recvMessage);
            byte[] bRecvMessage = new byte[iRecvMessageLen];
            System.arraycopy(bTemp,0,bRecvMessage,0,iRecvMessageLen);
            return bRecvMessage;
        } catch (IOException e) {
            XxlJobLogger.log("Recv Message Error:" + e.getMessage());
            return null;
        }
    }



    public boolean isConnect() {
        try {
            if (socket != null && socket.isConnected()) {
                socket.sendUrgentData(0xFF);
                return true;
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public void close() {
        try {
            if (!socket.isInputShutdown()) {
                socket.shutdownInput();
            }
            if (!socket.isOutputShutdown()) {
                socket.shutdownOutput();
            }
            if (socket != null && !socket.isClosed()) {
                socket.close();
                socket = null;
            }
        } catch (Exception e) {
            XxlJobLogger.log("close socket exption:" + e.getMessage());
        }
    }


    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }


}
